---
title: What are Tools?
sidebarTitle: Overview
description: Tools are functions your Agno Agents can use to get things done.
---

Tools are what make Agents capable of real-world action. While using LLMs directly you can only generate text, Agents equipped with tools can interact with external systems and perform practical actions.

They are used to enable Agents to interact with external systems, and perform actions like searching the web, running SQL, sending an email or calling APIs.

Agno comes with 120+ pre-built toolkits, which you can use to give your Agents all kind of abilities. You can also write your own tools, to give your Agents even more capabilities. The general syntax is:


```python
import random

from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.tools import tool

# This is our tool, marked by the @tool decorator
@tool(stop_after_tool_call=True)
def get_weather(city: str) -> str:
    """Get the weather for the given city."""

    # In a real implementation, this would call a weather API
    weather_conditions = ["sunny", "cloudy", "rainy", "snowy", "windy"]
    random_weather = random.choice(weather_conditions)

    return f"The weather in {city} is {random_weather}."

# To equipt our Agent with our tool, we simply pass it with the tools parameter
agent = Agent(
    model=OpenAIChat(id="gpt-5-nano"),
    tools=[get_weather],
    markdown=True,
)

# Our Agent will now be able to use our tool, when it deems it relevant
agent.print_response("What is the weather in San Francisco?", stream=True)
```

<Tip>
In the example above, the `get_weather` function is a tool. When called, the tool result is shown in the output.

Then, the Agent will stop after the tool call (without waiting for the model to respond) because we set `stop_after_tool_call=True`.

</Tip>

### Using the Toolkit Class

The `Toolkit` class provides a way to manage multiple tools with additional control over their execution.

You can specify which tools should stop the agent after execution and which should have their results shown.

```python
from agno.agent import Agent
from agno.models.openai import OpenAIChat

# Importing our GoogleSearchTools ToolKit, containing multiple web search tools
from agno.tools.googlesearch import GoogleSearchTools

agent = Agent(
    model=OpenAIChat(id="gpt-5-mini"),
    tools=[
        GoogleSearchTools(),
    ],
)

agent.print_response("What's the latest about OpenAIs GPT-5?", markdown=True)
```

In this example, the `GoogleSearchTools` toolkit is added to the agent. This ToolKit comes pre-configured with the `google_search` function.

## Tool Built-in Parameters

Agno automatically provides special parameters to your tools that give access to the agent's state. These parameters are injected automatically - you don't pass them when calling the tool.

### Using the Run Context

You can access values from the current run via the `run_context` parameter: `run_context.session_state`, `run_context.dependencies`, `run_context.knowledge_filters`, `run_context.metadata`. See the [RunContext schema](/reference/run/run_context) for more information.

This allows tools to access and modify persistent data across conversations.

This is useful in cases where a tool result is relevant for the next steps of the conversation.

Add `run_context` as a parameter in your tool function to access the agent's persistent state:

```python
from agno.agent import Agent
from agno.db.sqlite import SqliteDb
from agno.models.openai import OpenAIChat
from agno.run import RunContext


def add_item(run_context: RunContext, item: str) -> str:
    """Add an item to the shopping list."""
    if not run_context.session_state:
        run_context.session_state = {}

    run_context.session_state["shopping_list"].append(item)  # type: ignore
    return f"The shopping list is now {run_context.session_state['shopping_list']}"  # type: ignore


# Create an Agent that maintains state
agent = Agent(
    model=OpenAIChat(id="gpt-4o-mini"),
    # Initialize the session state with a counter starting at 0 (this is the default session state for all users)
    session_state={"shopping_list": []},
    db=SqliteDb(db_file="tmp/agents.db"),
    tools=[add_item],
    # You can use variables from the session state in the instructions
    instructions="Current state (shopping list) is: {shopping_list}",
    markdown=True,
)

# Example usage
agent.print_response("Add milk, eggs, and bread to the shopping list", stream=True)
print(f"Final session state: {agent.get_session_state()}")
```

See more in [Agent State](/concepts/agents/state).

### Media Parameters

The built-in parameter `images`, `videos`, `audio`, and `files` allows tools to access and modify the input media to an agent.

<Note>
Using the `send_media_to_model` parameter, you can control whether the media is sent to the model or not and using `store_media` parameter, you can control whether the
media is stored in the `RunOutput` or not.
</Note>

See the [image input example](/examples/concepts/agent/multimodal/image_input_for_tool) and [file input example](/examples/concepts/agent/multimodal/file_input_for_tool) for an advanced example using media.

## Tool Results

Tools can return different types of results depending on their complexity and what they need to communicate back to the agent.

### Simple Return Types

Most tools can return simple Python types directly like `str`, `int`, `float`, `dict`, and `list`:

```python
@tool
def get_weather(city: str) -> str:
    """Get the weather for a city."""
    return f"The weather in {city} is sunny and 75°F"

@tool
def calculate_sum(a: int, b: int) -> int:
    """Calculate the sum of two numbers."""
    return a + b

@tool
def get_user_info(user_id: str) -> dict:
    """Get user information."""
    return {
        "user_id": user_id,
        "name": "John Doe",
        "email": "john@example.com",
        "status": "active"
    }

@tool
def search_products(query: str) -> list:
    """Search for products."""
    return [
        {"id": 1, "name": "Product A", "price": 29.99},
        {"id": 2, "name": "Product B", "price": 39.99}
    ]
```

### `ToolResult` for Media Content

When your tool needs to return media artifacts (images, videos, audio), you **must** use `ToolResult`:

<Snippet file="tool-result-reference.mdx" />

```python
from agno.tools.function import ToolResult
from agno.media import Image

@tool
def generate_image(prompt: str) -> ToolResult:
    """Generate an image from a prompt."""

    # Create your image (example)
    image_artifact = Image(
        id="img_123",
        url="https://example.com/generated-image.jpg",
        original_prompt=prompt
    )

    return ToolResult(
        content=f"Generated image for: {prompt}",
        images=[image]
    )
```

This would **make generated media available** to the LLM model.

## Guides

<CardGroup cols={2}>
  <Card
    title="Available Toolkits"
    icon="box-open"
    href="/concepts/tools/toolkits"
  >
    See the full list of available toolkits
  </Card>
  <Card
    title="MCP Tools"
    icon="robot"
    href="/concepts/tools/mcp"
  >
    Learn how to use MCP tools with Agno
  </Card>
  <Card
    title="Reasoning Tools"
    icon="brain-circuit"
    href="/concepts/tools/reasoning_tools"
  >
    Learn how to use reasoning tools with Agno
  </Card>
  <Card
    title="Creating your own tools"
    icon="code"
    href="/concepts/tools/custom-tools"
  >
    Learn how to create your own tools
  </Card>
</CardGroup>
